


class Link
  
  STATUS_PENDING = "new"
  STATUS_DOWNLOADING = "downloading"
  STATUS_FINISHED = "finished"
  STATUS_FAILED = "failed"
  STATUS_CANCELLED = "cancelled"
  
  attr_accessor :url
  attr_accessor :name
  attr_accessor :status
  attr_accessor :cookie
  attr_accessor :destination
  
  attr :downloaded_bytes
  attr :pct_bytes
  attr :total_bytes
  
  
  
  
  def initialize(url, download_location)
    @url = url.strip
    
    # TODO replace with regex
    if @url.split('/').size <= 1
      raise "invalid link"
    end
    
    @name = @url.split('/').last
    @destination = download_location + @name
    
    @total_bytes = 0
    @downloaded_bytes = 0
    @pct_bytes = 1
    @status = Link::STATUS_PENDING
  end
  
  def progress
    @downloaded_bytes / @pct_bytes
  end
  
  def download_start(cookie)
    puts "starting download of " + @name
    redirect_http = Net::HTTP.new(URI.parse(@url).host)
    headers = {
      'Cookie' => cookie
    }
    
    redirect_url = redirect_http.get(URI.parse(@url).path, headers).header['location']
    puts "url : " + redirect_url
    
    host = URI.parse(redirect_url).host
    path = URI.parse(redirect_url).path
    downloadhttp = Net::HTTP.new(host)
    
    header = downloadhttp.head(path, headers)
    @total_bytes =  header['content-length'].to_i
    @pct_bytes = @total_bytes / 100
    @downloaded_bytes = 0
    
    @status = STATUS_DOWNLOADING
    
    File.open(@destination, 'w') {|f|
      downloadhttp.get(path, headers) do |str|
        if (@status != STATUS_DOWNLOADING) 
          break
        end
        f.write str
        @downloaded_bytes += str.size
      end
      
    }
    if @status == STATUS_DOWNLOADING
      @status = STATUS_FINISHED
    end
    
  end
  
  def cancel
    if @status == STATUS_DOWNLOADING
      @status = STATUS_CANCELLED
    end
  end
end
